#include "stream.h"//加载头文件
#if ECBM_STREAM_EN//检查本库有没有被使能
/*--------------------------------------变量定义-----------------------------------*/
u8 xdata ecbm_stream_buf[ECBM_STREAM_SZIE];
u8 ecbm_stream_start =0;
u8 ecbm_stream_stop  =0;
u8 ecbm_stream_count =0;
u8 ecbm_stream_time  =0;
u8 ecbm_stream_status=0;
/*--------------------------------------程序定义-----------------------------------*/
/*-------------------------------------------------------
流处理主函数函数。
-------------------------------------------------------*/
void ecbm_stream_main(void){
    //进入处理的条件：
    if(ecbm_stream_status&ECBM_STREAM_TIME_OUT){//必须是接收超时状态，这个状态代表已经过了一段时间没有新的数据过来了。
        if((ecbm_stream_count>0)&&(ecbm_stream_count<ECBM_STREAM_SZIE)){//判断接收到的数据的数量是否合法。
            ecbm_stream_status&=~ECBM_STREAM_TIME_OUT;  //开始处理数据了，清除这个标志位。
            while(ecbm_stream_count){
                ecbm_stream_exe(ecbm_stream_buf[ecbm_stream_start]);
                ecbm_stream_start++;
                if(ecbm_stream_start>=ECBM_STREAM_SZIE){
                    ecbm_stream_start=0;
                }
                ecbm_stream_count--;
            }
            ecbm_stream_start=ecbm_stream_stop;
        }else{//如果不合法的话，就执行下面的动作。
            if(ecbm_stream_count>=ECBM_STREAM_SZIE){    //如果是接收的数据超过了队列的容忍范围，
                ecbm_stream_count=0;                    //考虑到数据可能已经严重损失，将抛弃掉这些数据。
            }
        }
    }
    if(ecbm_stream_status&ECBM_STREAM_UART_IDLE){
        ecbm_stream_status&=~ECBM_STREAM_UART_IDLE;  //清除这个标志位。
        #if ECBM_STREAM_FUR_EN
            es_fur_status=FUR_READY;
        #endif
        #if ECBM_STREAM_MODBUS_EN
            es_modbus_rtu_status=ES_MODBUS_RTU_READY;
        #endif
        #if ECBM_STREAM_ECP_EN
            es_ecp_status=ES_ECP_READY;
        #endif
        #if ECBM_STREAM_XMODEM_EN
            es_xmodem_status=ES_XMODEM_STOP; 
        #endif

    }
}
/*-------------------------------------------------------
流处理比对函数。
-------------------------------------------------------*/
#if ECBM_STREAM_CMP_EN
void ecbm_stream_strcmp(u8 dat,u8 code * str,u8 * count){
    if(str[*count]==dat){    //判断一下当前串口数据和关键字的某个字符是否一样。
        (*count)++;          //一样的话，计数+1，下次循环就会判断下一个字符了。
    }else{                   //不一样的话，
        *count=0;            //计数清零。但是在本次循环中，计数清零会引入关键字的一个新字符。
        if(str[*count]==dat){//既然出现了新字符就要判断下是否与当前串口数据符合。
            (*count)++;      //符合就计数+1。
        }
    }
}
#endif
/*-------------------------------------------------------
CRC16校验函数。
-------------------------------------------------------*/
#if (ECBM_STREAM_MODBUS_EN+ECBM_STREAM_ECP_EN)
u16 es_crc16(u16 crc,u8 buf){
    u8 j;
    u16 crc_buf;
    crc_buf=crc^buf;                    //当前数据异或CRC低字节，在C51里可以直接处理。
    for(j=0;j<8;j++){                   //计算每个字节的每一位。
        if(crc_buf&0x01){               //判断右移前最低位是否为1。
            crc_buf=(crc_buf>>1)^0xA001;//如果为1则右移并异或表达式。
        }else{
            crc_buf>>=1;                //否则直接右移一位。
        }           
    }
    return crc_buf;
}
#endif
#endif  //和最上面的#ifndef配合成一个程序段。
        //以一个空行为结尾。